package com.ds.iot.device;

import com.ds.common.JDSException;
import com.ds.common.query.*;
import com.ds.common.util.StringUtility;
import com.ds.config.ErrorListResultModel;
import com.ds.config.ErrorResultModel;
import com.ds.config.ListResultModel;
import com.ds.config.ResultModel;
import com.ds.home.query.IOTConditionKey;
import com.ds.iot.*;
import com.ds.iot.ct.CtIotFactory;
import com.ds.iot.device.XUIDevice;
import com.ds.iot.device.XUIGateway;
import com.ds.iot.device.XUIHAParam;
import com.ds.iot.device.XUIZNode;
import com.ds.iot.enums.DeviceDataTypeKey;
import com.ds.iot.enums.DeviceStatus;
import com.ds.web.util.PageUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

@Controller
@RequestMapping("/iot/device")
public class IotDeviceService {

    @RequestMapping(value = {"/getAllGWDevice"}, method = {RequestMethod.GET, RequestMethod.POST})
    public @ResponseBody
    ListResultModel<List<XUIGateway>> getAllGWDevice(String factoryName, String ieee) {
        ListResultModel<List<XUIGateway>> userStatusInfo = new ListResultModel<List<XUIGateway>>();
        List<XUIGateway> modules = new ArrayList<XUIGateway>();

        Condition<IOTConditionKey, JLuceneIndex> condition = new Condition<>(IOTConditionKey.DEVICE_STATES, Operator.NOT_EQUAL, DeviceStatus.DELETE.getCode());
        if (factoryName != null && !factoryName.equals("")) {
            Condition factoryCondition = new Condition<IOTConditionKey, JLuceneIndex>(IOTConditionKey.DEVICE_FACTORY, Operator.EQUALS, factoryName);
            condition.addCondition(factoryCondition, JoinOperator.JOIN_AND);
        }

        if (ieee != null && !ieee.equals("")) {
            Condition<IOTConditionKey, JLuceneIndex> ieeecondition = new Condition<>(IOTConditionKey.DEVICE_SERIALNO, Operator.LIKE, "%" + ieee + "%");
            condition.addCondition(ieeecondition, JoinOperator.JOIN_AND);
        }

//
//        Condition<IOTConditionKey, JLuceneIndex> typecondition = new Condition<>(IOTConditionKey.DEVICE_DEVICETYPE, Operator.EQUALS, 0);
//        condition.addCondition(typecondition, JoinOperator.JOIN_AND);


        Condition endcondition = new Condition(IOTConditionKey.DEVICE_LASTLOGINTIME,
                Operator.GREATER_THAN, (System.currentTimeMillis() - (5 * 1000 * 60)));
        condition.addCondition(endcondition, JoinOperator.JOIN_AND);


        Order order = new Order(IOTConditionKey.DEVICE_LASTLOGINTIME, false);
        condition.addOrderBy(order);


        ListResultModel<List<Device>> devices = null;
        try {
            devices = CtIotFactory.getAdminClient().findDevice(condition);
            userStatusInfo = PageUtil.changPageList(devices, XUIGateway.class);
        } catch (JDSException e) {
            userStatusInfo = new ErrorListResultModel<>();
            ((ErrorListResultModel) userStatusInfo).setErrcode(e.getErrorCode());
            ((ErrorListResultModel) userStatusInfo).setErrdes(e.getMessage());
        }

        return userStatusInfo;


    }


    @RequestMapping(value = {"/findDevices"}, method = {RequestMethod.GET, RequestMethod.POST})
    public @ResponseBody
    ListResultModel<List<XUIDevice>> findDevice(String factoryName, String ieee, String batch, String devicetype) {
        ListResultModel<List<XUIDevice>> userStatusInfo = new ListResultModel<List<XUIDevice>>();
        List<XUIDevice> modules = new ArrayList<XUIDevice>();
        Condition<IOTConditionKey, JLuceneIndex> condition = new Condition<>(IOTConditionKey.DEVICE_STATES, Operator.NOT_EQUAL, DeviceStatus.DELETE.getCode());
        if (factoryName != null && !factoryName.equals("")) {
            Condition factoryCondition = new Condition<IOTConditionKey, JLuceneIndex>(IOTConditionKey.DEVICE_FACTORY, Operator.EQUALS, factoryName);
            condition.addCondition(factoryCondition, JoinOperator.JOIN_AND);
        }
        if (ieee != null && !ieee.equals("")) {
            Condition<IOTConditionKey, JLuceneIndex> ieeecondition = new Condition<>(IOTConditionKey.DEVICE_SERIALNO, Operator.LIKE, "%" + ieee + "%");
            condition.addCondition(ieeecondition, JoinOperator.JOIN_AND);
        }

        if (devicetype != null && !devicetype.equals("")) {
            Condition<IOTConditionKey, JLuceneIndex> ieeecondition = new Condition<>(IOTConditionKey.DEVICE_SERIALNO, Operator.EQUALS, devicetype);
            condition.addCondition(ieeecondition, JoinOperator.JOIN_AND);
        }

        if (batch != null && !batch.equals("")) {
            Condition<IOTConditionKey, JLuceneIndex> ieeecondition = new Condition<>(IOTConditionKey.DEVICE_SERIALNO, Operator.EQUALS, devicetype);
            condition.addCondition(ieeecondition, JoinOperator.JOIN_AND);
        }

//        Condition<IOTConditionKey,JLuceneIndex> typecondition=new Condition<>(IOTConditionKey.DEVICE_DEVICETYPE,Operator.EQUALS,0);
//        condition.addCondition(typecondition,JoinOperator.JOIN_AND);

        ListResultModel<List<Device>> devices = null;
        try {
            devices = CtIotFactory.getAdminClient().findDevice(condition);
            userStatusInfo = PageUtil.changPageList(devices, XUIDevice.class);
        } catch (JDSException e) {
            userStatusInfo = new ErrorListResultModel<>();
            ((ErrorListResultModel) userStatusInfo).setErrcode(e.getErrorCode());
            ((ErrorListResultModel) userStatusInfo).setErrdes(e.getMessage());
        }

        return userStatusInfo;
    }

    @RequestMapping(value = {"/getEndPointInfo"}, method = {RequestMethod.GET, RequestMethod.POST})
    public @ResponseBody
    ResultModel<XUISensor> getEndPointInfo(String ieee) {
        ResultModel<XUISensor> userStatusInfo = new ResultModel<XUISensor>();
        try {
            List<XUIHAParam> modules = new ArrayList<XUIHAParam>();
            DeviceEndPoint ep = CtIotFactory.getCtIotService().getEndPointByIeee(ieee);
            userStatusInfo.setData(new XUISensor(ep));
        } catch (JDSException e) {
            userStatusInfo = new ErrorResultModel<>();
            ((ErrorResultModel) userStatusInfo).setErrcode(e.getErrorCode());
            ((ErrorResultModel) userStatusInfo).setErrdes(e.getMessage());
        }


        return userStatusInfo;
    }


    @RequestMapping(value = {"/getHAParams"}, method = {RequestMethod.GET, RequestMethod.POST})
    public @ResponseBody
    ListResultModel<List<XUIHAParam>> getHAParams(String ieee) {
        ListResultModel<List<XUIHAParam>> userStatusInfo = new ListResultModel<List<XUIHAParam>>();
        try {
            List<XUIHAParam> modules = new ArrayList<XUIHAParam>();
            DeviceEndPoint ep = CtIotFactory.getCtIotService().getEndPointByIeee(ieee);
            Iterator it = ep.getCurrvalue().keySet().iterator();
            while (it.hasNext()) {
                String key = it.next().toString();
                DeviceDataTypeKey dkey = DeviceDataTypeKey.fromType(key);
                XUIHAParam xuihaParam = new XUIHAParam();
                xuihaParam.setDesc(dkey.getName());
                xuihaParam.setKey(dkey.getType());
                Object value = ep.getCurrvalue().get(dkey);
                if (value != null) {
                    xuihaParam.setValue(value.toString());
                } else {
                    xuihaParam.setValue("");
                }

                xuihaParam.setType(dkey.getParamType().getName());
                modules.add(xuihaParam);
            }
            userStatusInfo.setSize(modules.size());
            userStatusInfo.setData(modules);
        } catch (JDSException e) {
            userStatusInfo = new ErrorListResultModel<>();
            ((ErrorListResultModel) userStatusInfo).setErrcode(e.getErrorCode());
            ((ErrorListResultModel) userStatusInfo).setErrdes(e.getMessage());
        }


        return userStatusInfo;
    }




    @RequestMapping(value = {"/getChildDevices"}, method = {RequestMethod.GET, RequestMethod.POST})
    public @ResponseBody
    ListResultModel<List<Device>> getChildDevices(String gwieee) {

        List<DeviceEndPoint> deviceEndPoints = new ArrayList<DeviceEndPoint>();
        ListResultModel<List<Device>> userStatusInfo = new ListResultModel<List<Device>>();
        List<Device> modules = new ArrayList<Device>();
        Device device = null;
        try {
            device = CtIotFactory.getCtIotService().getDeviceByIeee(gwieee);
            List<Device> childdevices = device.getChildDevices();
            for (Device childdevice : childdevices) {
                modules.add(childdevice);
            }
            userStatusInfo.setSize(modules.size());
            userStatusInfo.setData(modules);
        } catch (JDSException e) {
            userStatusInfo = new ErrorListResultModel();
            ((ErrorListResultModel) userStatusInfo).setErrcode(e.getErrorCode());
            ((ErrorListResultModel) userStatusInfo).setErrdes(e.getMessage());
        }

        return userStatusInfo;
    }


    @RequestMapping(value = {"/updateEPName"}, method = {RequestMethod.GET, RequestMethod.POST})
    public @ResponseBody
    ResultModel<Boolean> updateEPName(String ieee, String alias) {
        DeviceEndPoint endPoint = null;
        ResultModel<Boolean> userStatusInfo = new ResultModel<Boolean>();
        try {
            CtIotFactory.getAdminClient().updateEndPointName(ieee, alias);
        } catch (JDSException e) {
            e.printStackTrace();
        }
        return userStatusInfo;
    }

    @RequestMapping(value = {"/deleteDevices"}, method = {RequestMethod.GET, RequestMethod.POST})
    public @ResponseBody
    ResultModel<Boolean> deleteDevices(String deviceIds) {
        DeviceEndPoint endPoint = null;
        ResultModel<Boolean> userStatusInfo = new ResultModel<Boolean>();
        String[] deviceIdArr = deviceIds.split(";");

        try {
            CtIotFactory.getAdminClient().clearDevices(Arrays.asList(deviceIdArr));
        } catch (JDSException e) {
            userStatusInfo = new ErrorResultModel();
            ((ErrorResultModel) userStatusInfo).setErrcode(e.getErrorCode());
            ((ErrorResultModel) userStatusInfo).setErrdes(e.getMessage());
        }

        return userStatusInfo;
    }


    @RequestMapping(value = {"/deleteDevice"}, method = {RequestMethod.GET, RequestMethod.POST})
    public @ResponseBody
    ResultModel<Boolean> deleteDevice(String deviceId) {
        DeviceEndPoint endPoint = null;
        ResultModel<Boolean> userStatusInfo = new ResultModel<Boolean>();
        try {
            CtIotFactory.getAdminClient().deleteDevice(deviceId);
        } catch (JDSException e) {
            userStatusInfo = new ErrorResultModel();
            ((ErrorResultModel) userStatusInfo).setErrcode(e.getErrorCode());
            ((ErrorResultModel) userStatusInfo).setErrdes(e.getMessage());
        }
        return userStatusInfo;
    }


    @RequestMapping(value = {"/getAllChildDevices"}, method = {RequestMethod.GET, RequestMethod.POST})
    public @ResponseBody
    ListResultModel<List<XUISensor>> getAllChildDevices(String gwieee) {
        List<DeviceEndPoint> deviceEndPoints = new ArrayList<DeviceEndPoint>();
        ListResultModel<List<XUISensor>> userStatusInfo = new ListResultModel<List<XUISensor>>();
        List<XUISensor> modules = new ArrayList<XUISensor>();
        Device device = null;
        try {
            device = CtIotFactory.getCtIotService().getDeviceByIeee(gwieee);
            List<Device> childdevices = device.getChildDevices();
            for (Device childdevice : childdevices) {
                List<DeviceEndPoint> endpoints = childdevice.getDeviceEndPoints();
                for (DeviceEndPoint endpoint : endpoints) {
                    XUISensor module = new XUISensor(endpoint);
                    modules.add(module);
                }
            }
        } catch (JDSException e) {
            userStatusInfo = new ErrorListResultModel();
            ((ErrorListResultModel) userStatusInfo).setErrcode(e.getErrorCode());
            ((ErrorListResultModel) userStatusInfo).setErrdes(e.getMessage());
        }
        userStatusInfo.setSize(modules.size());
        userStatusInfo.setData(modules);
        return userStatusInfo;
    }
    @RequestMapping(value = {"/getZnodes"}, method = {RequestMethod.GET, RequestMethod.POST})
    public @ResponseBody
    ListResultModel<List<XUIZNode>> getZnodes(String ieee, String placeid, String areaid) {
        ListResultModel<List<XUIZNode>> userStatusInfo = new ListResultModel<List<XUIZNode>>();

        try {
            if (ieee!=null && !ieee.equals("")){
                DeviceEndPoint deviceEndPoint = CtIotFactory.getCtIotService().getEndPointByIeee(ieee);
                List<ZNode> znodes = deviceEndPoint.getAllZNodes();
                userStatusInfo = PageUtil.getDefaultPageList(znodes, XUIZNode.class);
            }else  if (areaid!=null && !areaid.equals("")){
                Area area = CtIotFactory.getCtIotService().getAreaById(areaid);
                List<ZNode> znodes = area.getSensors();
                userStatusInfo = PageUtil.getDefaultPageList(znodes, XUIZNode.class);


        }else  if (placeid!=null && !placeid.equals("")){
                Place place = CtIotFactory.getCtIotService().getPlaceById(placeid);
                List<ZNode> znodes = place.getSensors();
                userStatusInfo = PageUtil.getDefaultPageList(znodes, XUIZNode.class);
            }

        } catch (JDSException e) {
            userStatusInfo = new ErrorListResultModel();
            ((ErrorListResultModel) userStatusInfo).setErrcode(e.getErrorCode());
            ((ErrorListResultModel) userStatusInfo).setErrdes(e.getMessage());
        }


        return userStatusInfo;
    }



    @RequestMapping(value = {"/deleteZNode"}, method = {RequestMethod.GET, RequestMethod.POST})
    public @ResponseBody
    ResultModel<Boolean> deleteZNode(String znodeIds) {
        ResultModel<Boolean> userStatusInfo = new ResultModel<Boolean>();

        String[] nodeIdArr = StringUtility.split(znodeIds, ";");
        try {
            for (String nodeId : nodeIdArr) {
                CtIotFactory.getAdminClient().deleteZNode(nodeId);
            }
        } catch (JDSException e) {
            userStatusInfo = new ErrorResultModel();
            ((ErrorResultModel) userStatusInfo).setErrcode(e.getErrorCode());
            ((ErrorResultModel) userStatusInfo).setErrdes(e.getMessage());
        }


        return userStatusInfo;
    }


}
